# 可迭代对象
# 迭代: 遍历 - 一次从对象中把元素取出来的过程
# 可迭代的数据类型: str, list, tuple, set, dict, range
# 可迭代对象: 对象实现了 __iter__() 方法
# 可迭代对象的 __iter__() 方法返回一个迭代器对象
# for 循环会自动调用可迭代对象的 __iter__() 方法
# 对获取到的迭代器对象调用 __next__() 方法获取下一个元素

from collections.abc import Iterable,Iterator

# isinstance: 判断对象是否是某个类的实例
print(isinstance("ssss", Iterable))  # True, 字符串是可迭代对象
print(isinstance("ssss", str))  # True, 字符串是可迭代对象
print(isinstance("ssss", list))  # False
print(isinstance([1,2], list))  # True
print(isinstance([1,2], (list,dict,str)))  # True
print(isinstance([1,2], dict))  # False

print("-------------- 2 --------------")
# 迭代器时候一个可以记住遍历位置的对象. 在上次停留的位置继续遍历

# iter: 返回一个迭代器对象
# next: 获取迭代器的下一个元素

items = [1,2,3,4,5]
# 创建迭代器对象
print("-------------- 方式一: iter() + next  --------------")
items_back = iter(items)
print(items_back) # <list_iterator object at 0x7f8a50075670>
e1 = next(items_back) #
print(e1)
e2 = next(items_back)
print(e2)
e3 = next(items_back)
print(e3)
e4 = next(items_back)
print(e4)
e5 = next(items_back)
print(e5)
# e6 = next(items_back)
# print(e6) # StopIteration: 没有更多元素可迭代

# iter()调用对象的 __iter__()方法并把__iter__()方法返回的迭代器对象返回
# next()调用对象的 __next__()方法并返回下一个元素
# 迭代器对象的 __next__()方法会抛出 StopIteration 异常表示没有更多元素可迭代

print("-------------- 方式2: while  --------------")

items_backup = iter(items)
while True:
    try:
        item = next(items_backup)
        print(item)
    except StopIteration:
        print("没有更多元素可迭代")
        break

print("-------------- 方式23: iter + __next__()  --------------")
items_backup_2 = iter(items)
print(items_backup_2.__next__())
print(items_backup_2.__next__())
print(items_backup_2.__next__())
print(items_backup_2.__next__())
print(items_backup_2.__next__())


print(dir(items)) # No __next__() method, so it is not an iterator
print(dir(items_back)) # Has __next__() method, so it is an iterator

# 可迭代对象iterable 和 迭代器 iterator 的区别:
# 凡是可以作用于for循环的都属于可迭代对象iterable
# 凡事可以作用于 next()函数的都属于迭代器iterator

name = "leslie"
isinstance(name, Iterable) # True, 字符串是可迭代对象
isinstance(name, Iterator) # False, 字符串不是迭代器对象
# 可迭代对象并不一定是迭代器对象
name2 = iter(name)  # 创建迭代器对象,将可迭代对象转换成迭代器对象
isinstance(name2, Iterable) # True, 字符串是可迭代对象
isinstance(name2, Iterator) # True, 字符串是可迭代对象



